package com.topwalk.step01.thread_local;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashSet;
import java.util.Set;

/**
 * 线程不安全的情况下
 *
 * @author tangfl
 */
@RestController
@RequestMapping("/orders")
public class OrderController {

    private Integer count = 0;
    private static final Set<Val<Integer>> SET = new HashSet<>();
    private static final ThreadLocal<Val<Integer>> TL = ThreadLocal.withInitial(() -> {
        Val<Integer> val = new Val<>();
        val.setV(0);
        addSet(val);
        return val;
    });

    @GetMapping("/visit")
    public Integer visit() throws InterruptedException {
        Thread.sleep(100);
        this.add();
        return 0;
    }

    private synchronized void add() {
        count++;
    }

    @GetMapping("/visit/tl")
    public Integer visitThreadLocal() throws InterruptedException {
        Thread.sleep(100);
        Val<Integer> val = TL.get();
        val.setV(val.getV() + 1);
        return 0;
    }


    @GetMapping("/stat")
    public Integer stat() {
        return count;
    }

    @GetMapping("/stat/tl")
    public Integer stateTl() {
        return TL.get().getV();
    }

    @GetMapping("/stat/hs")
    public Integer stateHashSet() {
        return SET.stream().map(Val::getV).reduce(Integer::sum).orElse(-1);
    }

    private static synchronized void addSet(Val<Integer> val) {
        SET.add(val);
    }

}